/**
 *
 */
package com.jsfclassic.controller.menu;

import com.jsfclassic.controller.navigation.NavigationConstants;
import com.jsfclassic.controller.navigation.Navigator;
import com.jsfclassic.controller.navigation.PersonalNavigationConstants;
import com.jsfclassic.controller.navigation.UserNavigationConstants;
import java.io.Serializable;
import javax.el.ExpressionFactory;
import javax.el.MethodExpression;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.MethodExpressionActionListener;
import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.submenu.Submenu;
import org.primefaces.model.DefaultMenuModel;
import org.primefaces.model.MenuModel;

/**
 * @author alobato
 *
 */
@ManagedBean
@SessionScoped
public class MenuManager implements Serializable {

    private static final String TARGET = "target";
    private static final long serialVersionUID = 4012893488829841335L;
    private String menuSelected;
    @ManagedProperty(value = "#{navigator}")
    Navigator navigator;
    private MenuModel model;

    public void createMenu() {
        model = new DefaultMenuModel();

        // Configuration submenu
        Submenu submenuUser = new Submenu();
        submenuUser.setLabel("User");
        submenuUser.getChildren().add(createItem("user", UserNavigationConstants.user));
        model.addSubmenu(submenuUser);



        Submenu submenuPersonal = new Submenu();
        submenuPersonal.setLabel("Perosonal");
        submenuPersonal.getChildren().add(createItem("Perosonal", PersonalNavigationConstants.personal));
        submenuPersonal.getChildren().add(createItem("list Perosonal", PersonalNavigationConstants.listPersonal));
        model.addSubmenu(submenuPersonal);

        model.addMenuItem(createItem("Page1", NavigationConstants.page1));
    }

    private MenuItem createItem(String value, String target) {
        MenuItem item = new MenuItem();
        item.setValue(value);


        //item.setTarget(target);
        //item.setUpdate("contenido");
        item.setActionExpression(createMethodExpression(target, String.class, new Class[]{String.class}));
        item.getAttributes().put(TARGET, target);
        item.addActionListener(createMethodActionListener(
                "#{menuManager.changePageAction}", String.class,
                new Class[]{ActionEvent.class}));

        item.setAjax(false);
        return item;
    }

    public MenuModel getModel() {
        if (model == null) {
            createMenu();
        }
        return model;
    }

    public void changePageAction(ActionEvent event) {
        MenuItem selectedMenuItem = (MenuItem) event.getComponent();
        menuSelected = selectedMenuItem.getAttributes().get(TARGET).toString();
        navigator.navigateTo(menuSelected);
    }

    private MethodExpression createMethodExpression(String valueExpression,
            Class<?> valueType, Class<?>[] expectedParamTypes) {
        MethodExpression methodExpression = null;
        try {
            ExpressionFactory factory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
            methodExpression = factory.createMethodExpression(FacesContext.getCurrentInstance().getELContext(), valueExpression,
                    valueType, expectedParamTypes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return methodExpression;
    }

    private MethodExpressionActionListener createMethodActionListener(
            String valueExpression, Class<?> valueType,
            Class<?>[] expectedParamTypes) {
        MethodExpressionActionListener actionListener = null;
        try {
            actionListener = new MethodExpressionActionListener(
                    createMethodExpression(valueExpression, valueType,
                    expectedParamTypes));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return actionListener;
    }

    /**
     * @return the menuSelected
     */
    public String getMenuSelected() {
        return menuSelected;
    }

    /**
     * @param menuSelected
     *            the menuSelected to set
     */
    public void setMenuSelected(String menuSelected) {
        this.menuSelected = menuSelected;
    }

    public Navigator getNavigator() {
        return navigator;
    }

    public void setNavigator(Navigator navigator) {
        this.navigator = navigator;
    }
}
